/**
 * @file test_temp.cpp
 * @author 杨剑 (yangjian@autocruis.com)
 * @brief 模板文件
 * @version 1.0
 * @date 2023/01/12
 * @copyright Copyright (c) 2023 Auotcruis (wuhan), Inc.
 * par 修改日志:
 * <table>
 * <tr><th>修改日期     <th>作者  <th>修改内容
 */
#include "c_defines.h"
#include "glut_win.h"
#include "shader_mgr.h"
#include <glm/ext.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>

using namespace std;

void Init(void)
{
    glClearColor(.22f, .21f, .23f, 0.f);

    // 开启点的平滑减少锯齿
    glEnable(GL_POINT_SMOOTH);
    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);

    // 启用线的反走样
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_BLEND); // 混合与线的平滑需要同时启用，减少锯齿
    glBlendFunc(GL_ONE, GL_ONE_MINUS_DST_ALPHA);
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_MULTISAMPLE);

    auto shader = CShaderManager::GetInstance().CreateNewShader("line");
    shader->LoadShader("../shader/line.vert", "../shader/line.frag", 2, 0, "vVertexs", 1, "vColor");
}

void Display()
{
    static auto shader = CShaderManager::GetInstance().GetShader("line");

    // 获取着色器属性
    // static auto projLoc = glGetUniformLocation(shader, "projection");
    // static auto viewLoc = glGetUniformLocation(shader, "view");
    // static auto modelLoc = glGetUniformLocation(shader, "model");
    // static auto colorLoc = glGetUniformLocation(shader, "color");

    static glm::mat4 projection = glm::perspective(glm::radians(75.f), GLfloat(640) / GLfloat(480), 1.f, 100000.f);
    static glm::mat4 view = glm::lookAt(glm::vec3(0.f, 15.f, -10.f), glm::vec3(0.f), glm::vec3(0.f, 1000.f, -10.f));
    static glm::mat4 model = glm::scale(glm::mat4(1.f), glm::vec3(1.f));

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    shader->Enable();
    // 设置属性值
    shader->SetUniformMatrix4fv("projection", glm::value_ptr(projection));
    shader->SetUniformMatrix4fv("view", glm::value_ptr(view));
    shader->SetUniformMatrix4fv("model", glm::value_ptr(model));

    // todo something

    shader->Disable();

    glFinish();
}

int main(int argc, char **argv)
{
    CGlutWindow window("shader test");

    window.Init(&argc, argv);

    Init();

    window.RegisterCallbackFunc([]() {
        glutDisplayFunc(Display);
        glutIdleFunc(Display);
    });

    window.MainLoop();

    return 0;
}